Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Popsicle is a versatile HTTP request library for Node.js and the browser. It provides a simple and consistent API for making HTTP requests, handling responses, and managing various aspects of HTTP communication such as headers, query parameters, and request/response bodies.
Making HTTP Requests
This feature allows you to make HTTP requests to a specified URL. The example demonstrates a GET request to a JSON placeholder API, logging the status and body of the response.
const { request } = require('popsicle');
request('https://jsonplaceholder.typicode.com/posts/1')
.then(response => {
console.log(response.status);
console.log(response.body);
})
.catch(error => {
console.error(error);
});
Handling Query Parameters
This feature allows you to include query parameters in your HTTP requests. The example demonstrates a GET request with a query parameter to filter posts by userId.
const { request } = require('popsicle');
request({
url: 'https://jsonplaceholder.typicode.com/posts',
query: { userId: 1 }
})
.then(response => {
console.log(response.status);
console.log(response.body);
})
.catch(error => {
console.error(error);
});
Setting Headers
This feature allows you to set custom headers for your HTTP requests. The example demonstrates setting the 'Content-Type' header to 'application/json'.
const { request } = require('popsicle');
request({
url: 'https://jsonplaceholder.typicode.com/posts',
headers: { 'Content-Type': 'application/json' }
})
.then(response => {
console.log(response.status);
console.log(response.body);
})
.catch(error => {
console.error(error);
});
Handling Request and Response Bodies
This feature allows you to handle request and response bodies. The example demonstrates a POST request with a JSON body to create a new post.
const { request } = require('popsicle');
request({
method: 'POST',
url: 'https://jsonplaceholder.typicode.com/posts',
body: { title: 'foo', body: 'bar', userId: 1 },
headers: { 'Content-Type': 'application/json' }
})
.then(response => {
console.log(response.status);
console.log(response.body);
})
.catch(error => {
console.error(error);
});
Axios is a popular promise-based HTTP client for the browser and Node.js. It provides a simple API for making HTTP requests and handling responses, similar to Popsicle. Axios is known for its ease of use and wide adoption in the JavaScript community.
Node-fetch is a lightweight module that brings `window.fetch` to Node.js. It is a minimalistic library that provides a simple API for making HTTP requests, similar to the Fetch API in the browser. Node-fetch is often used for its simplicity and compatibility with the Fetch API standard.
Superagent is a small progressive client-side HTTP request library, and Node.js module with a similar API. It provides a flexible and powerful API for making HTTP requests and handling responses. Superagent is known for its extensive feature set and ease of use.
Popsicle is the easiest way to make HTTP requests - a consistent, intuitive and tiny API that works on node and the browser. 9.37 kB in browsers, after minification and gzipping, including dependencies (with
url
being the bulk of it).
popsicle.get('/users.json')
.then(function (res) {
console.log(res.status) //=> 200
console.log(res.body) //=> { ... }
console.log(res.headers) //=> { ... }
})
npm install popsicle --save
const popsicle = require('popsicle')
popsicle.request({
method: 'POST',
url: 'http://example.com/api/users',
body: {
username: 'blakeembrey',
password: 'hunter2'
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.use(popsicle.plugins.parse('json'))
.then(function (res) {
console.log(res.status) // => 200
console.log(res.body) //=> { ... }
console.log(res.get('Content-Type')) //=> 'application/json'
})
Popsicle is a promise-based HTTP request library designed for extensibility. Here's the functions you can import from popsicle
:
get
)defaults
Request
classResponse
class"GET"
).{}
).Infinity
)[stringify(), headers()]
)createTransport({ type: 'text' })
)stringify
(default)Automatically serialize the request body into a string (E.g. JSON, URL-encoded or multipart).
headers
(default)Sets up default headers for environments. For example, Content-Length
, User-Agent
, Accept
, etc.
parse
Automatically parses allowed response type(s).
popsicle.get('/users')
.use(popsicle.plugins.parse(['json', 'urlencoded']))
.then(() => ...)
Popsicle provides two transports, one for node (using {http,https}.request
) and one for browsers (using XMLHttpRequest
). These transports have a number of "types" built-in for handling the response body.
responseType === 'document'
(browsers)responseType === 'blob'
(browsers)responseType === 'arraybuffer'
(browsers)Uint8Array
(node.js)Node transport options
text
)true
)popsicle.jar()
) (default: null
)5
)2000000
)true
)307
and 308
status codes (default: () => false
)Buffer
or array of strings or Buffers
of trusted certificates in PEM formatnull
)null
)Browser transport options
text
)false
)Common methods have a short hand exported (created using defaults({ method })
).
popsicle.get('http://example.com/api/users')
popsicle.post('http://example.com/api/users')
popsicle.put('http://example.com/api/users')
popsicle.patch('http://example.com/api/users')
popsicle.del('http://example.com/api/users')
Create a new Popsicle instance with defaults pre-populated. Handy for a common cookie jar or transport to be used.
const cookiePopsicle = popsicle.defaults({
transport: popsicle.createTransport({
jar: popsicle.jar()
})
})
Popsicle will automatically serialize the request body using the stringify
plugin. If an object is supplied, it will automatically be stringified as JSON unless the Content-Type
was set otherwise. If the Content-Type
is application/json
, multipart/form-data
or application/x-www-form-urlencoded
, it will be automatically serialized accordingly.
popsicle.get({
url: 'http://example.com/api/users',
body: {
username: 'blakeembrey'
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
You can manually create a FormData
instance by calling popsicle.form
. When you pass a form data instance as the body, it'll automatically set the correct Content-Type
- complete with boundary.
const form = popsicle.form({
username: 'blakeembrey',
profileImage: fs.createReadStream('image.png')
})
form.append('x', 'y')
popsicle.post({
url: '/users',
body: form
})
You can create a reusable cookie jar instance for requests by calling popsicle.jar
.
const jar = popsicle.jar()
popsicle.request({
method: 'post',
url: '/users',
transport: popsicle.createTransport({
jar: jar
})
})
Calling any of the request functions will return an instance of Request
.
PopsicleError
instance.Request
from toOptions()
.abort
event.P.S. When cloning a request instance, the current middleware and events are copied. This allows event tricks like abort()
to also abort cloned request instances (e.g. in the case where working with request retries, and aborting should still work on re-attempts).
Promises are the most expressive interface. Just chain using Request#then
or Request#catch
and continue.
popsicle.get('/users')
.then(function (res) {
// Success!
})
.catch(function (err) {
// Something broke.
})
If you live on the edge, try with generators (co) or ES7 async
/await
.
co(function * () {
const users = yield popsicle.get('/users')
})
async function () {
const users = await popsicle.get('/users')
}
For tooling that expects node-style callbacks, you can use Request#exec
. This accepts a single function to call when the response is complete.
popsicle.get('/users')
.exec(function (err, res) {
if (err) {
// Something broke.
}
// Success!
})
All requests can be aborted before or during execution by calling Request#abort
.
const request = popsicle.get('http://example.com')
setTimeout(function () {
request.abort()
}, 100)
request.catch(function (err) {
console.log(err) //=> { message: 'Request aborted', code: 'EABORTED' }
})
The request object can be used to check progress at any time.
All percentage properties (request.uploaded
, request.downloaded
, request.completed
) are a number between 0
and 1
. Aborting the request will emit a progress event, if the request had started.
const request = popsicle.get('http://example.com')
request.uploaded //=> 0
request.downloaded //=> 0
request.on('progress', function () {
console.log(request) //=> { uploaded: 1, downloaded: 0, completed: 0.5, aborted: false }
})
request.then(function (response) {
console.log(request.downloaded) //=> 1
})
All response methods can return an error. Errors have a popsicle
property set to the request object and a code
string. The built-in codes are documented below, but custom errors can be created using request.error(message, code, cause)
.
Every response will give a Response
instance on success. T
200 -> 2
)application/json
)Plugins can be set as an array with the initial options (which overrides default plugins), or they can be used via Request#use
.
supertest
)throat
- Throttle promise-based functions with concurrency supportis-browser
- Check if your in a browser environment (E.g. Browserify, Webpack)parse-link-header
- Handy for parsing HTTP link headersPlugins must be a function that accept config and return a middleware function. For example, here's a basic URL prefix plugin.
function prefix (url) {
return function (self, next) {
self.url = url + self.url
return next()
}
}
popsicle.request('/user')
.use(prefix('http://example.com'))
.then(function (response) {
console.log(response.url) //=> "http://example.com/user"
})
Middleware functions accept two arguments - the current request and a function to proceed to the next middleware function (a la Koa 2.x
).
P.S. The middleware array is exposed on request.middleware
, which allows you to clone requests and tweak middleware - for example, using request.middleware.slice(request.middleware.indexOf(currentFn))
. This is useful, as the pre and post steps of previous middleware attach before currentFn
is executed.
Creating a custom transportation layer is just a matter creating an object with open
, abort
and use
options set. The open method should set any request information required between called as request._raw
. Abort must abort the current request instance, while open
must always resolve to a promise. You can set use
to an empty array if no plugins should be used by default. However, it's recommended you keep use
set to the defaults, or as close as possible using your transport layer.
This module is designed for ES5 environments, but requires two ES2015 polyfills to work:
Promise
- popsicle
is designed heavily with promises in mindObject.assign
- used internally for object cloningThis project is written using TypeScript and typings. Since version 1.3.1
, you can install the type definition using typings
.
typings install npm:popsicle --save
Note that for a brand new project you might need to add the definition for node via the following command:
typings install env~node --save --global
Make sure you add typings/index.d.ts
to your TypeScript project (using files
or includes
in tsconfig.json
) if it isn't already.
Install dependencies and run the test runners (node and Electron using Tape).
npm install && npm test
MIT
FAQs
Advanced HTTP requests in node.js and browsers
The npm package popsicle receives a total of 211,855 weekly downloads. As such, popsicle popularity was classified as popular.
We found that popsicle demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.